﻿// ----------------------------------
// Depends on:
//   jQuery
//   jQuery.form
//   Microsoft.Ajax
// ----------------------------------

Type.registerNamespace("MyLib");

MyLib.WebRequestExecutor = function (sourceElement) {
	MyLib.WebRequestExecutor.initializeBase(this);

	// for properties
	this._started = false;
	this._responseAvailable = false;
	this._timedOut = false;
	this._aborted = false;
	this._responseData = null;
	this._statusCode = null;

	// the element initiated the async postback
	this._sourceElement = sourceElement;
	// the form in the page.
	this._form = Sys.WebForms.PageRequestManager.getInstance()._form;
}

MyLib.WebRequestExecutor.prototype =
{
	get_started: function () {
		return this._started
	},

	get_responseAvailable: function () {
		return this._responseAvailable;
	},

	get_timedOut: function () {
		return this._timedOut;
	},

	get_aborted: function () {
		return this._aborted;
	},

	get_responseData: function () {
		return this._responseData;
	},

	get_statusCode: function () {
		return this._statusCode;
	},

	executeRequest: function () {
		this._addAdditionalHiddenElements();

		var onSuccess = Function.createDelegate(this, this._onSuccess);
		var onFailure = Function.createDelegate(this, this._onFailure);

		this._started = true;

		var timeout = this._webRequest.get_timeout();
		if (timeout > 0) {
			this._timer = window.setTimeout(Function.createDelegate(this, this._onTimeout), timeout);
		}

		jQuery(this._form).ajaxSubmit({
			dataType: "text",
			error: onFailure,
			success: onSuccess
		});
	},

	_addHiddenElement: function (name, value) {
		var hidden = document.createElement("input");
		hidden.name = name;
		hidden.value = value;
		hidden.type = "hidden";
		this._form.appendChild(hidden);
		Array.add(this._hiddens, hidden);
	},

	_addAdditionalHiddenElements: function () {
		var prm = Sys.WebForms.PageRequestManager.getInstance();

		this._hiddens = [];

		var requestBody = this.get_webRequest().get_body();
		var requestArray = requestBody.split("&");
		for (var i in requestArray) {
			var requestItem = requestArray[i];
			var requestNameValue = requestItem.split("=");
			var requestName = decodeURIComponent(requestNameValue[0]);

			var requestElement = jQuery("[name='" + requestName + "']", this._form)
				.not(":submit")
				.not("input:image");

			if (requestElement.size() == 0) {
				var requestValue = decodeURIComponent(requestNameValue[1]);
				this._addHiddenElement(requestName, requestValue);
			}
		}
	},

	_removeAdditionalHiddenElements: function () {
		var hiddens = this._hiddens;
		delete this._hiddens;

		for (var i = 0; i < hiddens.length; i++) {
			hiddens[i].parentNode.removeChild(hiddens[i]);
		}

		hiddens.length = 0;
	},

	_onSuccess: function (responseData) {
		this._clearTimer();
		if (this._aborted || this._timedOut) return;

		this._statusCode = 200;
		this._responseAvailable = true;
		this._responseData = responseData;

		this._removeAdditionalHiddenElements();
		this.get_webRequest().completed(Sys.EventArgs.Empty);
	},

	_onFailure: function () {
		this._clearTimer();
		if (this._aborted || this._timedOut) return;

		this._statusCode = 500;
		this._responseAvailable = false;

		this._removeAdditionalHiddenElements();
		this.get_webRequest().completed(Sys.EventArgs.Empty);
	},

	abort: function () {
		this._aborted = true;
		this._clearTimer();

		this._removeAdditionalHiddenElements();
	},

	_onTimeout: function () {
		this._timedOut = true;

		this._statusCode = 500;
		this._responseAvailable = false;

		this._removeAdditionalHiddenElements();
		this.get_webRequest().completed(Sys.EventArgs.Empty);
	},

	_clearTimer: function () {
		if (this._timer != null) {
			window.clearTimeout(this._timer);
			delete this._timer;
		}
	}
}

MyLib.WebRequestExecutor.registerClass("MyLib.WebRequestExecutor", Sys.Net.WebRequestExecutor);

Sys.Application.add_init(function () {
	Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(function (sender, e) {
		e.get_request().set_executor(new MyLib.WebRequestExecutor(e.get_postBackElement()));
	});
});

if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
